#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project : gtmsAutoTestProject 
@File    : food_list_server.py
@IDE     : PyCharm 
@Author  : Mario
@Date    : 2022/6/23 11:55 
@Describe: 菜品列表数据组装
"""
import random
from APIs.posApi.food.food_api import FoodApi
from Comm.tools.toolsControl import ToolsHandler


def get_taste_fish_data(fish_data):
    """
    获取口味菜品中的鱼类信息
    :param fish_data: 鱼类数据
    :return:
    """
    fish_data_list = []  # 返回数据空列表
    fish_dict = {
        "foodCode": fish_data[0]['foodItemDetailList'][0]['foodCode'],  # 口味菜品第一条鱼的菜品编码
        "foodMadeList": [],
        "foodNum": 1,
        "foodType": 1,
        "subjectItemKey": fish_data[0]['foodItemDetailList'][0]['subjectItemKey']
    }  # 口味菜品鱼数据字典
    fish_data_list.append(fish_dict)  # 把口味菜品鱼数据字典加入到数据空列表
    return fish_data_list


def get_fixings_group_food_list(food_data: dict) -> list:
    """
    获取口味菜品中的辅菜信息
    :param food_data: 口味菜品数据
    :return:
    """
    fixingsGroupFoodList = []  # 辅菜空列表
    commonFixingsGroupFoodList = food_data.get('commonFixingsGroupFoodList')  # 获取口味菜品的常规辅菜组合
    if commonFixingsGroupFoodList is not None:  # 判断获取的到的辅菜组合是否不为空，如果为特殊口味的话就不用传辅菜数据
        food_dict = {
            "foodCode": commonFixingsGroupFoodList[0]['foodCode'],  # 固定取第一个辅菜数据
            "foodMadeList": [],
            "foodNum": 1,
            "foodType": 1
        }  # 辅菜数据字典
        fixingsGroupFoodList.append(food_dict)  # 将辅菜数据加入到辅菜空列表
    return fixingsGroupFoodList


class FoodListServer:

    def __init__(self, brandCode, environment):
        """
        构造函数
        :param brandCode: 品牌编码
        :param environment: 环境
        """
        self.food_api = FoodApi(brandCode, environment)  # 实例化菜品接口请求类

    def get_food_info(self, jsonpath: str):
        """
        获取菜品信息
        :param jsonpath: jsonpath提取表达式
        :return:
        """
        response = self.food_api.food_list()  # 调用POS菜品列表接口获取菜品数据
        food_data = ToolsHandler.get_json_result(response, jsonpath)  # 使用jsonpath方法提取需要的数据
        return food_data

    def get_base_food_data(self):
        """
        获取单品数据,不含做法，不含限购
        :return:
        """
        # 提取菜品类型为单品并且库存大于0并且限购类型等于1的单品数据(限购类型(1-不限,2-每单会员限购,3-每单限购))
        json_path = '$..foodDetailList[?(@.foodType==1 && @.totalStock>0 && @.saleLimitType==1)]'
        base_food_data = self.get_food_info(json_path)  # 调用get_food_info方法获取菜品数据
        if type(base_food_data) is list:  # TODO:(钟昀) 判断取出的数据是否为list类型，正常情况都是list类型如果不是说明没有符合的菜品数据，情况极低，后续可以加上对应处理
            is_run = True  # 是否执行，用于下面的while循环
            while is_run is True:  # 判断is_run是否为True,不为True就一直执行，理论上不会出现死循环
                random_int = random.randint(0, len(base_food_data) - 1)  # 用单品菜品列表长度算出随机数，-1是因为随机数从0开始，不减少1可能出现数组越界可能
                random_base_food_data = base_food_data[random_int]  # 取出随机的菜品数据
                # TODO:(钟昀) 此处可能出现死循环的情况，需要优化
                if random_base_food_data.get('foodMadeList') is None:  # 判断随机的菜品做法是否为空，如果所有的菜品数据都有做法的话会出现死循环的情况
                    is_run = False  # 如果菜品做法为空，说明菜品没有做法，这时候就把is_run的状态改为False跳出循环
                    base_food_data_dict = {
                        "foodNum": 1,  # 菜品数量
                        "foodType": 1,
                        "foodCode": random_base_food_data['foodCode']  # 单品编码
                    }
                    return base_food_data_dict

    def meal_food_list(self, food_data) -> list:
        """
        菜品子项列表
        :param food_data: 菜品数据
        :return:
        """
        mealFoodList = []  # 套餐/第二份N折/口味菜品所属的菜品子项列表
        for i in range(len(food_data)):  # 循环菜品列表
            # itemType:菜品项类型（默认1：固定菜品；2：可选菜品；3：主菜：4：原价菜品；5：半价菜品）
            itemType = food_data[i]['itemType']
            # 调用food_made_list方法获取菜品做法信息
            meal_food_list = self.food_made_list(food_data[i], itemType)
            for x in range(len(meal_food_list)):  # 循环菜品做法信息列表
                mealFoodList.append(meal_food_list[x])  # 将菜品做法信息放入mealFoodList列表
        return mealFoodList

    def food_made_list(self, food_data, item_type) -> list:
        """
        菜品做法信息
        :param food_data: 菜品数据
        :param item_type: 菜品项类型（默认1：固定菜品；2：可选菜品；3：主菜：4：原价菜品；5：半价菜品）
        :return:
        """
        food_made_list = []  # 菜品做法空列表
        foodItemDetailList = food_data['foodItemDetailList']  # 菜品项详情列表
        if item_type == 1:  # 判断菜品类型是否为固定菜品
            for x in range(len(foodItemDetailList)):  # 循环菜品项详情列表
                # 调用suit_food_data_cleaning方法进行数据清洗
                suit_data = self.suit_food_data_cleaning(foodItemDetailList[x])
                food_made_list.append(suit_data)  # 将清洗后的数据加入food_made_list列表
        elif item_type == 2:  # 判断菜品类型是否为可选菜品
            # 调用suit_food_data_cleaning方法进行数据清洗
            suit_data = self.suit_food_data_cleaning(foodItemDetailList[0])
            food_made_list.append(suit_data)  # 将清洗后的数据加入food_made_list列表
        return food_made_list

    def suit_food_data_cleaning(self, suit_data):
        """
        套餐数据清洗
        :param suit_data: 菜品数据
        :return:
        """
        foodCode = suit_data['foodCode']  # 菜品编码
        subjectItemKey = suit_data['subjectItemKey']  # 套餐子项唯一主键
        foodMadeList = suit_data.get('foodMadeList')  # 菜品做法信息，这里使用get方法主要是为了下面的判断，如果没取到值返回为None
        # 判断套餐子项是否为口味商品
        if foodMadeList is not None:  # 如果为口味菜品则需要查出口味的做法
            madeCode = suit_data['foodMadeList'][0]['madeDetailList'][0]['madeCode']  # 做法编码
            Made_List = self.food_taste_require_list(madeCode)  # 调用food_taste_require_list方法获取做法列表
            made_list = {
                "madeCode": madeCode,
                "madeName": suit_data['foodMadeList'][0]['madeDetailList'][0]['madeName'],
                "madeType": suit_data['foodMadeList'][0]['madeDetailList'][0]['madeType'],
                "raisePrice": suit_data['foodMadeList'][0]['madeDetailList'][0]['raisePrice'],
                "subjectMadeKey": suit_data['foodMadeList'][0]['madeDetailList'][0]['subjectMadeKey']
            }
            Made_List.append(made_list)
        else:  # 如果子项不为口味菜品，菜品做法就是空的
            Made_List = []
        mealFoodDict = {
            "foodCode": foodCode,
            "foodMadeList": Made_List,
            "foodNum": 1,
            "foodType": 1,
            "subjectItemKey": subjectItemKey
        }  # 菜品子项数据字典
        return mealFoodDict

    def food_taste_require_list(self, madeCode) -> list:
        """
        菜品做法列表
        :param madeCode: 做法code
        :return:
        """
        foodMadeList = []  # 菜品做法空列表
        response = self.food_api.food_taste_require_list(madeCode)  # 调用口味菜品的要求列表接口获取菜品做法信息
        # 取出单选做法，因为单选做法为必选，多选非必选;singleChoice:是否单选(0:否,1:是)
        made_info = ToolsHandler.get_json_result(response, '$..data[?(@.singleChoice==1)]')
        if type(made_info) is dict:  # 判断取出的菜品做法信息类型是否字典类型,字典类型代表只有单个做法单选
            made_dict = {
                "madeCode": made_info['madeDetailList'][0]['madeCode'],  # 做法编码
                "madeName": made_info['madeDetailList'][0]['madeName'],  # 做法名称
                "madeType": made_info['madeDetailList'][0]['madeType'],  # 做法类型
                "raisePrice": made_info['madeDetailList'][0]['raisePrice'],  # 堂食做法加价
                "subjectMadeKey": made_info['madeDetailList'][0]['subjectMadeKey']  # 做法唯一主键
            }
            foodMadeList.append(made_dict)  # 将做法信息加入foodMadeList列表
        elif type(made_info) is list:  # 判断取出的菜品做法信息类型是否为列表,列表类型代表有多个做法
            for i in range(len(made_info)):  # 循环做法列表
                made_dict = {
                    "madeCode": made_info[i]['madeDetailList'][0]['madeCode'],
                    "madeName": made_info[i]['madeDetailList'][0]['madeName'],
                    "madeType": made_info[i]['madeDetailList'][0]['madeType'],
                    "raisePrice": made_info[i]['madeDetailList'][0]['raisePrice'],
                    "subjectMadeKey": made_info[i]['madeDetailList'][0]['subjectMadeKey']
                }
                foodMadeList.append(made_dict)
        return foodMadeList

    def get_suit_food_data(self):
        """
        获取套餐数据
        :return:
        """
        # 提取菜品类型为套餐并且库存大于0并且限购类型等于1的套餐数据(限购类型(1-不限,2-每单会员限购,3-每单限购))
        json_path = '$..foodDetailList[?(@.foodType==2 && @.totalStock>0 && @.saleLimitType==1)]'
        suit_food_data = self.get_food_info(json_path)  # 调用get_food_info方法获取菜品数据
        random_int = random.randint(0, len(suit_food_data) - 1)  # 用套餐菜品列表长度算出随机数，-1是因为随机数从0开始，不减少1可能出现数组越界可能
        random_suit_food_data = suit_food_data[random_int]  # 取到随机的套餐数据
        foodItemList = random_suit_food_data['foodItemList']  # 取出套餐菜品子项列表
        mealFoodList = self.meal_food_list(foodItemList)  # 调用meal_food_list方法获取子项菜品下单数据
        suit_food_data_dict = {
            "foodCode": random_suit_food_data['foodCode'],
            "foodNum": 1,
            "foodType": 2,
            "mealFoodList": mealFoodList,
            "secondDiscountFood": 0
        }
        return suit_food_data_dict

    def get_taste_food_data(self):
        """
        获取口味菜品下单数据
        :return:
        """
        # 提取菜品类型为口味并且库存大于0并且限购类型等于1的口味数据(限购类型(1-不限,2-每单会员限购,3-每单限购))
        json_path = '$..foodDetailList[?(@.foodType==3 && @.totalStock>0 && @.saleLimitType==1)]'
        taste_food_data = self.get_food_info(json_path)  # 调用get_food_info方法获取菜品数据
        random_int = random.randint(0, len(taste_food_data) - 1)  # 用口味菜品列表长度算出随机数，-1是因为随机数从0开始，不减少1可能出现数组越界可能
        random_suit_food_data = taste_food_data[random_int]  # 取到随机的口味数据
        fixingsGroupFoodList = get_fixings_group_food_list(random_suit_food_data)  # 辅菜列表
        foodMadeList = self.food_taste_require_list(random_suit_food_data['tasteFoodMade']['madeCode'])  # 菜品做法信息
        mealFoodList = get_taste_fish_data(random_suit_food_data['foodItemList'])  # 套餐/第二份N折/口味菜品所属的菜品子项列表
        taste_food_data_dict = {
            "fixingsGroupFoodList": fixingsGroupFoodList,  # 辅菜列表
            "foodCode": random_suit_food_data['foodCode'],  # 菜品编码
            "foodMadeList": foodMadeList,  # 菜品做法信息
            "foodNum": 1,  # 菜品数量
            "foodType": 3,  # 菜品类型(1=普通菜品;2=套餐菜品;3=口味菜品)
            "mealFoodList": mealFoodList,  # 套餐/第二份N折/口味菜品所属的菜品子项列表
            "secondDiscountFood": 0  # 第二份n折菜品（0：否，1：是）
        }
        return taste_food_data_dict


if __name__ == '__main__':
    test = FoodListServer('823882', 'sit')
    print(test.get_suit_food_data())
